//
// Created by 张 on 2025/2/20.
//

#include "upgrade.h"
#include <android/log.h>
#include <dirent.h>

#define LOG_TAG "UPGRADE_CHUNK"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)

std::vector<std::vector<uint8_t>> upgrade::splitFileIntoChunks(const char *filename, size_t chunk_size)
{
    std::vector<std::vector<uint8_t>> chunks;

    std::ifstream file(filename, std::ios::binary);
    if (!file.is_open())
    {
        LOGE("Failed to open file: %s", filename); // 如果文件打开失败
        return chunks;
    }
    else
    {
        LOGI("Successfully opened file: %s", filename); // 文件成功打开
    }
    while (true)
    {
        std::vector<uint8_t> buffer(chunk_size); // Using uint8_t instead of unsigned char
        file.read(reinterpret_cast<char *>(buffer.data()), chunk_size);
        std::streamsize bytes_read = file.gcount(); // Number of bytes actually read

        if (bytes_read == 0)
        {
            break; // End of file reached
        }

        buffer.resize(bytes_read); // Adjust size for the last chunk if smaller
        chunks.push_back(buffer);
    }

    file.close();
    return chunks;
}

void listFiles(const char *path) {
    DIR *dir = opendir(path);
    if (!dir) {
        LOGE("无法打开目录: %s", path);
        return;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != nullptr) {
        LOGI("C++ 层找到文件: %s", entry->d_name);
    }
    closedir(dir);
}

std::vector<std::vector<uint8_t>> upgrade::UPGRADE_CHUNKS(){
    listFiles("/storage/emulated/0/Download");
    std::vector<std::vector<uint8_t>> ans;
    Mdfu mdfu(5, "8081");
    std::vector<uint8_t> data;
    ans.push_back(mdfu.test_send_cmd(MdfuCmd::GET_CLIENT_INFO, data, true));
    ans.push_back(mdfu.test_send_cmd(MdfuCmd::START_TRANSFER, data, false));

    const char *filepath = "/storage/emulated/0/Download/AvironUCB_V2.img";
    size_t chunk_size = 143; // Size of each chunk
    std::vector<std::vector<uint8_t>> chunks = splitFileIntoChunks(filepath, chunk_size);
    for (const auto &chunk : chunks)
    {
        ans.push_back(mdfu.test_send_cmd(MdfuCmd::WRITE_CHUNK, chunk, false));
    }
    ans.push_back(mdfu.test_send_cmd(MdfuCmd::GET_IMAGE_STATE, data, false));
    ans.push_back(mdfu.test_send_cmd(MdfuCmd::END_TRANSFER, data, false));

    return ans;
}


